package com.tanhua.server.service;

import cn.hutool.core.collection.CollUtil;
import com.tanhua.dubbo.api.TestApi;
import com.tanhua.dubbo.api.UserInfoApi;
import com.tanhua.dubbo.api.mongo.TestSoulApi;
import com.tanhua.model.domain.Options;
import com.tanhua.model.domain.Result;
import com.tanhua.model.domain.UserInfo;
import com.tanhua.model.mongo.TestReport;
import com.tanhua.model.mongo.TestSoul;
import com.tanhua.model.vo.Answers;
import com.tanhua.model.vo.QuestionnaireVo;
import com.tanhua.model.vo.ReportVo;
import com.tanhua.server.interceptor.UserHolder;
import org.apache.dubbo.config.annotation.DubboReference;
import org.bson.types.ObjectId;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
public class TestSoulService {

    @DubboReference
    private TestSoulApi testSoulApi;     //mongodb

    @DubboReference
    private TestApi testApi;             //mysql

    @DubboReference
    private UserInfoApi userInfoApi;

    public List<QuestionnaireVo> queryTestList() {
        Long userId = UserHolder.getId();
        List<TestSoul> testSoulList = testSoulApi.selectByUserId(userId);  //根据用户id找出该用户的所有测试题
        Map<Object, TestSoul> testSoulMap = CollUtil.fieldValueMap(testSoulList, "questionnaireId");
        List<Long> questionnaireIds = new ArrayList<>();
        for (TestSoul testSoul : testSoulList) {
            Long questionnaireId = testSoul.getQuestionnaireId();
            questionnaireIds.add(questionnaireId);
        }
        List<QuestionnaireVo> voList = testApi.questionnaireList(questionnaireIds, testSoulMap);
        return voList;
    }

    //根据传入的answers集合,计算总得分
    public Integer getTotalScore(List<Answers> answers) {
        Integer totalScore = 0;
        List<String> optionIds = CollUtil.getFieldValues(answers, "optionId", String.class);
        List<Long> optionIdList = optionIds.stream().map(Long::valueOf).collect(Collectors.toList());
        List<Options> optionsList = testApi.findAllOption(optionIdList);
        for (Options options : optionsList) {
            totalScore += options.getScore();
        }
        return totalScore;
    }

    //根据得分和问卷id得到result
    public Result getResultByScore(Integer totalScore, Long questionnaireId) {
        Result result = testApi.getResultByScore(totalScore, questionnaireId);
        return result;
    }

    //根据结果，生成一个专属于用户的报告表
    public TestReport getReport(Result result, Long questionnaireId, Integer totalScore) {
        TestReport testReport = new TestReport();
        testReport.setQuestionnaireId(questionnaireId);
        Long userId = UserHolder.getId();
        UserInfo userInfo = userInfoApi.findById(userId);
        testReport.setUserId(userId);
        testReport.setGender(userInfo.getGender());
        testReport.setResultId(result.getId());
        testReport.setScore(totalScore);
        testReport.setId(ObjectId.get());
        testSoulApi.saveReport(testReport);

        return testReport;
    }

    //根据问题id获得问卷id
    public Long getQuestionnaireId(Long questionId) {
        Long questionnaireId = testApi.getQuestionnaireId(questionId);
        return questionnaireId;
    }

    //根据当前用户提交的问卷id，解锁下一个问卷
    public void unlockNext(Long questionnaireId) {
        testSoulApi.unlockNext(UserHolder.getId(), questionnaireId);
    }

    //根据报告id拼凑ReportVo对象
    public ReportVo getReportVo(String reportId) {
        TestReport testReport = testSoulApi.findByReportId(reportId);   //根据报告id获得报告
        Result result = testApi.findByResultId(testReport.getResultId());  //根据报告中的结果id获得结果
        List<Long> userIds = testSoulApi.getSimilarUsers(UserHolder.getId(), testReport.getScore());  //根据报告得分获得分数相近的用户id集合
        List<UserInfo> userInfos = null;
        if (userIds != null) {
            userInfos = userInfoApi.getUsersByIds(userIds);   //根据用户id集合获得用户集合
        }
        ReportVo reportVo = ReportVo.init(userInfos, result);   //拼凑ReportVo
        return reportVo;
    }
}
